﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AdbRegisterUtils
{
    // CMD终端封装类
    public class CmdTerminal : IDisposable
    {
        private Process cmdProcess;
        private Thread outputThread;
        private Thread errorThread;
        private bool isRunning = false;
        ProcessStartInfo startInfo;
        private Action<string, string> outputCallback; // 修改为两个参数：命令和输出

        // 新增：命令历史记录
        private List<string> _commandHistory = new List<string>();
        private string _lastCommand = string.Empty;

        public bool IsRunning => isRunning && cmdProcess != null && !cmdProcess.HasExited;

        public CmdTerminal(Action<string, string> outputCallback, string workingDirectory = null, bool showWindow = false)
        {
            this.outputCallback = outputCallback ?? throw new ArgumentNullException(nameof(outputCallback));
            StartCmdProcess(workingDirectory, showWindow);
        }

        private void StartCmdProcess(string workingDirectory, bool showWindow)
        {
            try
            {
                 startInfo = new ProcessStartInfo
                {
                    FileName = "cmd.exe",
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    CreateNoWindow = !showWindow,
                    WorkingDirectory = workingDirectory ?? Environment.CurrentDirectory,
                    StandardOutputEncoding = Encoding.UTF8,
                    StandardErrorEncoding = Encoding.UTF8
                };

                cmdProcess = new Process { StartInfo = startInfo };
                cmdProcess.Start();

                isRunning = true;

                // 启动输出读取线程
                outputThread = new Thread(ReadOutput);
                outputThread.IsBackground = true;
                outputThread.Start();

                // 启动错误读取线程
                errorThread = new Thread(ReadError);
                errorThread.IsBackground = true;
                errorThread.Start();

                Console.WriteLine($"[CmdTerminal] CMD终端已启动，工作目录: {workingDirectory ?? Environment.CurrentDirectory}");
                SendOutput("", "CMD 终端已启动...\r\n");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[CmdTerminal ERROR] 启动CMD进程失败: {ex.Message}");
                throw new Exception($"启动CMD进程失败: {ex.Message}", ex);
            }
        }

        private void ReadOutput()
        {
            try
            {
                using (StreamReader reader = cmdProcess.StandardOutput)
                {
                    while (isRunning && !reader.EndOfStream)
                    {
                        string line = reader.ReadLine();
                        if (!string.IsNullOrEmpty(line))
                        {
                            // 打印到控制台
                            if (!IsCommandEcho(line, _lastCommand))
                            {
                                Console.WriteLine($"[CmdTerminal OUTPUT] 命令: '{_lastCommand}' -> 输出: {line}");
                            }

                            SendOutput(_lastCommand, line + "\r\n");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (isRunning)
                {
                    Console.WriteLine($"[CmdTerminal ERROR] 输出读取错误: {ex.Message}");
                    SendOutput("", $"输出读取错误: {ex.Message}\r\n");
                }
            }
        }

        private void ReadError()
        {
            try
            {
                using (StreamReader reader = cmdProcess.StandardError)
                {
                    while (isRunning && !reader.EndOfStream)
                    {
                        string line = reader.ReadLine();
                        Console.WriteLine($"[CmdTerminal ERROR] 命令: '{_lastCommand}' -> 错误: {line}");
                        SendOutput(_lastCommand, $"[错误] {line}\r\n");
                    }
                }
            }
            catch (Exception ex)
            {
                if (isRunning)
                {
                    Console.WriteLine($"[CmdTerminal ERROR] 错误流读取错误: {ex.Message}");
                    SendOutput("", $"错误流读取错误: {ex.Message}\r\n");
                }
            }
        }

        /// <summary>
        /// 检查是否是命令回显
        /// </summary>
        private bool IsCommandEcho(string outputLine, string lastCommand)
        {
            if (string.IsNullOrEmpty(lastCommand)) return false;

            // 简单的命令回显检测逻辑
            return outputLine.Trim().Equals(lastCommand.Trim(), StringComparison.OrdinalIgnoreCase) ||
                   outputLine.StartsWith($">{lastCommand}") ||
                   outputLine.Contains(lastCommand);
        }

        private void SendOutput(string command, string text)
        {
            try
            {
                outputCallback?.Invoke(command, text);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[CmdTerminal ERROR] 输出回调异常: {ex.Message}");
                Debug.WriteLine($"输出回调异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 发送命令到CMD进程
        /// </summary>
        /// <param name="command">要执行的命令</param>
        public void SendCommand(string command)
        {
            if (!isRunning || cmdProcess.HasExited)
            {
                string errorMsg = "CMD进程未运行";
                Console.WriteLine($"[CmdTerminal ERROR] {errorMsg}");
                SendOutput("", $"{errorMsg}\r\n");
                return;
            }

            if (string.IsNullOrEmpty(command?.Trim()))
                return;

            try
            {
                // 记录最后执行的命令
                _lastCommand = command.Trim();
                _commandHistory.Add(_lastCommand);

                // 打印命令到控制台
                Console.WriteLine($"[CmdTerminal SEND] 发送命令: {_lastCommand}");

                // 发送命令到回调（第一个参数）
                SendOutput(_lastCommand, $"> {_lastCommand}\r\n");

                // 发送命令到进程
                cmdProcess.StandardInput.WriteLine(command);

                // 记录命令历史
                Console.WriteLine($"[CmdTerminal INFO] 命令已发送，历史命令数量: {_commandHistory.Count}");
            }
            catch (Exception ex)
            {
                string errorMsg = $"发送命令失败: {ex.Message}";
                Console.WriteLine($"[CmdTerminal ERROR] {errorMsg}");
                SendOutput("", $"{errorMsg}\r\n");
            }
        }

        /// <summary>
        /// 获取命令历史记录
        /// </summary>
        public List<string> GetCommandHistory()
        {
            Console.WriteLine($"[CmdTerminal INFO] 获取命令历史，共 {_commandHistory.Count} 条命令");
            return new List<string>(_commandHistory);
        }

        /// <summary>
        /// 获取最后执行的命令
        /// </summary>
        public string GetLastCommand()
        {
            Console.WriteLine($"[CmdTerminal INFO] 最后执行的命令: '{_lastCommand}'");
            return _lastCommand;
        }

        /// <summary>
        /// 停止CMD终端
        /// </summary>
        public void Stop()
        {
            Console.WriteLine($"[CmdTerminal INFO] 正在停止CMD终端...");
            isRunning = false;

            try
            {
                if (cmdProcess != null && !cmdProcess.HasExited)
                {
                    Console.WriteLine($"[CmdTerminal INFO] 发送exit命令并等待进程退出...");
                    cmdProcess.StandardInput.WriteLine("exit");
                    if (!cmdProcess.WaitForExit(2000))
                    {
                        Console.WriteLine($"[CmdTerminal WARNING] 进程未在指定时间内退出，强制终止...");
                        cmdProcess.Kill();
                    }
                    cmdProcess.Dispose();
                    cmdProcess = null;
                    Console.WriteLine($"[CmdTerminal INFO] CMD终端已停止");
                }
                else
                {
                    Console.WriteLine($"[CmdTerminal INFO] CMD进程已退出或为null");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[CmdTerminal ERROR] 停止CMD终端时发生异常: {ex.Message}");
                // 忽略关闭过程中的异常
            }
        }

        public void Dispose()
        {
            Console.WriteLine($"[CmdTerminal INFO] 正在释放CMD终端资源...");
            Stop();
            Console.WriteLine($"[CmdTerminal INFO] CMD终端资源已释放");
        }
    }
}